import 'package:flutter/cupertino.dart';
import 'package:ideology/shared/widgets/code_input/core/editor_controller.dart';
import 'package:ideology/shared/widgets/code_input/core/text_buffer.dart';

/// 桥接层：
///
/// 负责连接：
/// - **[TextEditingController]**（IME / EditableText）；
/// - **[TextBuffer]**（底层文本存储结构，支持高效插删）；
/// - **[EditorController]**（光标、选区控制器）。
///
/// 主要职责：
/// 1. **IME → 内部**
///    在 attach() 之后监听 [textController]，当用户通过 IME 输入/删除/移动光标时，
///    自动更新 [buffer] 和 [controller]；
/// 2. **内部 → IME**
///    当编辑器逻辑（例如拖拽选择、点击光标）更新了 [controller]，
///    需要调用 [syncSelectionToEditable] 把选择/光标状态回写到 [EditableText]，
///    保证平台输入法候选框位置正确。
///
/// 使用方式：
/// ```dart
/// final imeBridge = ImeBridge(
///   buffer: buffer,
///   controller: editorController,
///   textController: textController,
///   onAfterSync: () {
///     setState(() {}); // 或滚动到光标位置
///   },
/// )..attach();
/// ```
class ImeBridge {
  ImeBridge({
    required this.buffer,
    required this.controller,
    required this.textController,
    this.onAfterSync,
  });

  /// 文本存储（GapBuffer 实现，支持高效编辑）
  final TextBuffer buffer;

  /// 编辑器控制器（负责光标和选区）
  final EditorController controller;

  /// Flutter 内建的 TextEditingController（与 EditableText/IME 交互）
  final TextEditingController textController;

  /// 每次 IME 输入同步到 buffer/controller 后触发（例如宿主 setState 或滚动保证）
  final void Function()? onAfterSync;

  bool _attached = false;

  /// 用于监听 [textController] 的回调引用
  late final VoidCallback _listener = _handleTextEditingValueChanged;

  /// 开始监听 IME -> 内部同步
  void attach() {
    if (_attached) return;
    _attached = true;
    textController.addListener(_listener);
  }

  /// 停止监听
  void detach() {
    if (!_attached) return;
    _attached = false;
    textController.removeListener(_listener);
  }

  /// 销毁时调用（等价于 detach）
  void dispose() => detach();

  /// === IME → 内部同步 ===
  /// 当 IME 的 [TextEditingValue] 变化时：
  /// - 更新 [buffer] 的文本内容；
  /// - 更新 [controller] 的光标与选区；
  /// - 最后调用 [onAfterSync]。
  void _handleTextEditingValueChanged() {
    final value = textController.value;

    // 文本不同步则重建 buffer
    if (value.text != buffer.getText()) {
      buffer.delete(0, buffer.length);
      buffer.insert(0, value.text);
    }

    // 更新光标位置
    controller.cursorPosition =
        value.selection.extentOffset.clamp(0, buffer.length);

    // 更新选区（折叠时清除）
    if (value.selection.isCollapsed) {
      controller.clearSelection();
    } else {
      controller.setSelection(
        value.selection.baseOffset.clamp(0, buffer.length),
        value.selection.extentOffset.clamp(0, buffer.length),
      );
    }

    // 通知宿主
    onAfterSync?.call();
  }

  /// === 内部 → IME 同步 ===
  /// 把 [controller] 的选择/光标状态写回 [textController]，
  /// 保证 IME 联想/候选框位置正确。
  void syncSelectionToEditable() {
    final sel = TextSelection(
      baseOffset: controller.hasSelection
          ? controller.selectionStart
          : controller.cursorPosition,
      extentOffset: controller.hasSelection
          ? controller.selectionEnd
          : controller.cursorPosition,
    );

    // 仅在不同步时更新，避免循环触发 listener
    if (textController.selection.baseOffset != sel.baseOffset ||
        textController.selection.extentOffset != sel.extentOffset) {
      textController.value = textController.value.copyWith(selection: sel);
    }
  }
}
